From: Florian Müllner Date: Sun, 9 Jul 2023 23:20:53 +0000 (+0200) Subject: extensionUtils: Stop using RegExp for stack parsing X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~337^2~1^2~131 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=3289b79433b7e549a21035fc2ee5470344dde44d;p=gnome-shell.git extensionUtils: Stop using RegExp for stack parsing We currently use a regular expression to extract the exact file path from a stack line. That RE is no longer accurate: - we assume a line number at the end, but at one point the column number was added as well - stacks from ES modules use file:// URIs instead of plain paths Luckily that doesn't matter: We don't want to access any actual files, so all we need is a path that can be traversed and that contains the UUID. We can get that with simple string manipulation, so avoid the regex overhead. Part-of: --- diff --git a/js/misc/extensionUtils.js b/js/misc/extensionUtils.js index df43d9825..c60c4520c 100644 --- a/js/misc/extensionUtils.js +++ b/js/misc/extensionUtils.js @@ -77,35 +77,28 @@ function getCurrentExtension() { if (_extension) return _extension; - let stack = new Error().stack.split('\n'); - let extensionStackLine; + const basePath = '/gnome-shell/extensions/'; // Search for an occurrence of an extension stack frame // Start at 1 because 0 is the stack frame of this function - for (let i = 1; i < stack.length; i++) { - if (stack[i].includes('/gnome-shell/extensions/')) { - extensionStackLine = stack[i]; - break; - } - } - if (!extensionStackLine) - return null; + const [, ...stack] = new Error().stack.split('\n'); + const extensionLine = stack.find( + line => line.includes(basePath)); - // The stack line is like: - // init([object Object])@/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8 - // - // In the case that we're importing from - // module scope, the first field is blank: - // @/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8 - let match = new RegExp('@(.+):\\d+').exec(extensionStackLine); - if (!match) + if (!extensionLine) return null; // local import, as the module is used from outside the gnome-shell process // as well (not this function though) let extensionManager = imports.ui.main.extensionManager; - let path = match[1]; + // The exact stack line differs depending on where the function + // was called (function or module scope), and whether it's called + // from a module or legacy import (file:// URI vs. plain path). + // + // We don't have to care about the exact composition, all we need + // is a string that can be traversed as path and contains the UUID + const path = extensionLine.slice(extensionLine.indexOf(basePath)); let file = Gio.File.new_for_path(path); // Walk up the directory tree, looking for an extension with